﻿using System;
using System.Collections;
using System.Linq;
using System.Windows.Forms;
using System.Collections.Generic;
using PS_WSSDeploy_Package.Client;

namespace PS_WSSDeploy_Package.Settings
{
    public partial class SettingForm : Form
    {
        private IClientSettings ClientSettings { get; set; }
        private ConfigContainer ConfigContainer { get; set; }
        private bool Sandboxed { get; set; }
        private Config ActiveConfig { get; set; }
        private string ConfigPath { get; set; }

        public SettingForm(bool sandboxed, IClientSettings clientSettings, string configPath)
        {
            InitializeComponent();
            ClientSettings = clientSettings;

            ConfigPath = configPath;
            ConfigContainer = clientSettings.ConfigContainer;
            Sandboxed = sandboxed;

            UpdateActiveConfig();
            InitControls();
        }

        private void InitControls()
        {
            vConfigComboBox.DropDownWidth = 200;

            UpdateSandboxControls();

            UpdateData(false);
            UpdateEnableButtonOK();
            UpdateEnableCertificateControls();
        }

        private void UpdateSandboxControls()
        {
            labelConfigName.Text = Sandboxed ? "Site URL:" : "Server";
            cbWspContainsResources.Enabled = !Sandboxed;
            cbUseTargetPath.Enabled = !Sandboxed;
            cbCopyPdbForSandbox.Enabled = Sandboxed;
        }

        private void UpdateActiveConfig()
        {
            ActiveConfig = ConfigContainer.GetActiveConfig(Sandboxed);
        }

        private bool UpdateData(bool save)
        {
            try
            {
                if (save)
                {
                    UpdateConfigListItem(vConfigComboBox.Text);
                }
                else
                {
                    LoadControls();
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        private void LoadControls()
        {
            LoadConfigCombo();
            var config = ConfigContainer.GetActiveConfig(Sandboxed);
            if(config != null)
            {
                SetConfigToControls(config);
            }
        }

        private void LoadConfigCombo()
        {
            vConfigComboBox.Items.Clear();
          
            var names = ConfigContainer.GetConfigNames(Sandboxed);
            foreach (var name in names)
            {
                vConfigComboBox.Items.Add(name);
            }
        }

        private void GetConfigFromControls(ref Config config)
        {
            config.Name = vConfigComboBox.Text;
            if (Sandboxed)
            {
                config.SandboxSiteUrl = vConfigComboBox.Text;
                config.CopyPdbForSandbox = cbCopyPdbForSandbox.Checked;
            }
            else
            {
                config.ServerName = vConfigComboBox.Text;
                config.WspContainsResources = cbWspContainsResources.Checked;
                config.UseTargetPath = cbUseTargetPath.Checked;
            }

            config.RemoteDebuggerLogin = tbRemoteDbgLogin.Text;
            config.SetRemoteDebuggerPassword(tbRemoteDbgPassword.Text);
            config.UseCertificate = cbUseCertificate.Checked;
            config.CertificateFileName = tbCertFileName.Text;
            config.SetCertificateFilePassword(tbCertFilePassword.Text);
        }

        private void SetConfigToControls(Config config)
        {
            vConfigComboBox.Text = config.Name;
            if (!Sandboxed)
            {
                cbWspContainsResources.Checked = config.WspContainsResources;
                cbUseTargetPath.Checked = config.UseTargetPath;
            }
            tbRemoteDbgLogin.Text = config.RemoteDebuggerLogin;
            tbRemoteDbgPassword.Text = config.GetRemoteDebuggerPassword();
            cbCopyPdbForSandbox.Checked = config.CopyPdbForSandbox;
            cbUseCertificate.Checked = config.UseCertificate;
            tbCertFileName.Text = config.CertificateFileName;
            tbCertFilePassword.Text = config.GetCertificateFilePassword();
        }

        private void AddConfigListItem()
        {
            var config = new Config();
            SetConfigToControls(config);
        }

        private void UpdateConfigListItem(string name)
        {
            var config = ConfigContainer.GetConfig(Sandboxed, name);
            if(config != null)
            {
                GetConfigFromControls(ref config);
            }
            else
            {
                var newConfig = new Config();
                GetConfigFromControls(ref newConfig);
                ConfigContainer.AddConfig(Sandboxed, newConfig);
                UpdateActiveConfig();
            }
        }

        private void UpdateEnableButtonOK()
        {
            btnOK.Enabled = !string.IsNullOrEmpty(vConfigComboBox.Text);
        }

        private void UpdateEnableCertificateControls()
        {
            tbCertFileName.Enabled = cbUseCertificate.Checked;
            btnCertificateOpen.Enabled = cbUseCertificate.Checked;
            tbCertFilePassword.Enabled = cbUseCertificate.Checked;
        }

        //Events

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (!UpdateData(true))
                return;

            ConfigContainer.Save(ConfigPath);

            DialogResult = DialogResult.OK;
            Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void btnAddItem_Click(object sender, EventArgs e)
        {
            AddConfigListItem();
            vConfigComboBox.Focus();
            UpdateEnableButtonOK();
        }

        private void btnDeleteItem_Click(object sender, EventArgs e)
        {
            var name = vConfigComboBox.Text;
            var result = ConfigContainer.DeleteConfig(Sandboxed, name);
            if(result)
            {
                object curItem = vConfigComboBox.SelectedItem;
                if (curItem != null)
                {
                    vConfigComboBox.Items.Remove(curItem);
                }
                UpdateActiveConfig();
                if (ActiveConfig != null)
                {
                    SetConfigToControls(ActiveConfig);
                }
            }

            UpdateEnableButtonOK();
        }

        private void vConfigComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            var combo = sender as ComboBox;
            if(combo != null)
            {
                var name = Convert.ToString(combo.SelectedItem);
                if (!string.IsNullOrEmpty(name))
                {
                    ConfigContainer.SetActiveConfig(Sandboxed, name);
                    UpdateActiveConfig();
                    if (ActiveConfig != null)
                    {
                        SetConfigToControls(ActiveConfig);
                    }
                }
            }
        }

        private void vConfigComboBox_TextChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(vConfigComboBox.Text)) return;
            UpdateEnableButtonOK();
        }

        private void btnCertificateOpen_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK == openFileDialog1.ShowDialog())
            {
                tbCertFileName.Text = openFileDialog1.FileName;
            }
        }

        private void cbUseCertificate_CheckedChanged(object sender, EventArgs e)
        {
            UpdateEnableCertificateControls();
        }

        private void UpdateServerCntrl(IEnumerable<string> servers)
        {
            vConfigComboBox.Text = string.Join(",", servers);
        }

        private string GetInputConfigName()
        {
            var configList = vConfigComboBox.Text;
            var configs = configList.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            return configs.Length > 0 ? configs[0] : string.Empty;
        }


        private void CheckButton_Click(object sender, EventArgs e)
        {
            var name = GetInputConfigName();
            if (string.IsNullOrEmpty(name)) return;

            Cursor.Current = Cursors.WaitCursor;
            try
            {
                if (Sandboxed)
                {
                    var uri = new Uri(name);
                    var serverName = uri.Host;
                    ClientSettings.GetFarmServerList(serverName);
                    MessageBox.Show(WssDeployResources.MessageBox_TestConnectionSucceeded);
                }
                else
                {
                    var servers = ClientSettings.GetFarmServerList(name);
                    MessageBox.Show(WssDeployResources.MessageBox_TestConnectionSucceeded);
                    UpdateServerCntrl(servers);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
    }
}
